package com.lzx.spring3.aop.jdk;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import com.lzx.spring3.dao.UserDao;
import com.lzx.spring3.dao.impl.UserDaoImpl;
import com.lzx.spring3.meta.User;
import com.lzx.spring3.meta.Watch;

public class Main {

	public static void main(String[] args) {

//		UserDao userDao = new UserDaoImpl();
//		boolean isProxyClass = Proxy.isProxyClass(userDao.getClass());
//		System.out.println(isProxyClass);
//		System.out.println(userDao);
//
//		for (Method m : userDao.getClass().getMethods()) {
//			System.out.println(m.getName() + "(" + getParameterTypes(m) + ")");
//		}
//
//		UserDao userDao2 = (UserDao) getProxy(new UserDaoImpl());
//		System.out.println(Proxy.isProxyClass(userDao2.getClass()));
//		System.out.println(userDao2);
//
//		userDao2.get2();
//		userDao2.delete(new User());
//
//		Class<?>[] interfaces = userDao2.getClass().getInterfaces();
//		for (Class<?> class1 : interfaces) {
//			System.out.println(class1.getName());
//			System.out.println(class1.getInterfaces()[0].getName());
//			for (Method m : class1.getMethods()) {
//				System.out.println(m.getName() + "(" + getParameterTypes(m)
//						+ ")");
//			}
//		}
//
//		System.out.println("============");
//
//		Method[] methods = userDao2.getClass().getMethods();
//		for (Method m : methods) {
//			System.out.println(m.getName() + "(" + getParameterTypes(m) + ")");
//		}
		
		
		
		UserDao userDao2 = (UserDao) getProxy(new UserDaoImpl());
		
		Watch.start();
		int count = 0;
		while (count < 5000000) {
			userDao2.get1(new User());
			userDao2.add(new User());
			count ++;
		}
		Watch.dis();

	}

	public static Object getProxy(final Object target) {
		return Proxy.newProxyInstance(Main.class.getClassLoader(), target
				.getClass().getInterfaces(), new InvocationHandler() {

			public Object invoke(Object proxy, Method method, Object[] args)
					throws Throwable {
//				method.setAccessible(true);
				return method.invoke(target, args);
			}
		});
	}

	public static String getParameterTypes(Method method) {
		StringBuilder sb = new StringBuilder();
		for (Class clz : method.getParameterTypes()) {
			sb.append(clz.getSimpleName() + ",");
		}
		return sb.toString();

	}

}
